<template>
  <div class="source"></div>
  <div class="mask" @mousedown="handleMouseDown" @mousemove="handleMouseMove"></div>
  <canvas
    ref="previewRef"
    class="preview"
    :style="{
      left: previewRect.left + 'px',
      top: previewRect.top + 'px',
      width: previewRect.width + 'px',
      height: previewRect.height + 'px'
    }"
    :width="previewRect.width"
    :height="previewRect.height"
  ></canvas>
  <div
    class="size"
    :style="{
      left: previewRect.left + 'px',
      top: previewRect.top - 24 + 'px'
    }"
  >
    {{ previewRect.width + ' x ' + previewRect.height + ' px' }}
  </div>
  <div
    class="tool"
    :style="{
      left: previewRect.left + previewRect.width - 80 + 'px',
      top: previewRect.top + previewRect.height + 5 + 'px'
    }"
  >
    <button @click="handleCancel">取消</button>
    <button @click="handleSave">确定</button>
  </div>
</template>

<script setup>
import { ref, onUnmounted } from 'vue'

const previewRef = ref(null)

const source = ref('')
const sourceContext = ref(null)
const selection = ref({
  flag: false,
  x: 0,
  y: 0
})

const previewRect = ref({
  left: 0,
  top: 0,
  width: 0,
  height: 0
})

const previewRectDisplay = ref('none')
const toolsDisplay = ref('none')

const handleMouseDown = (e) => {
  // if (previewRect.value.width) return

  selection.value.flag = true
  selection.value.x = e.offsetX
  selection.value.y = e.offsetY
  previewRectDisplay.value = 'block'
}

const handleMouseMove = (e) => {
  if (!selection.value.flag) return

  const left = Math.min(selection.value.x, e.offsetX)
  const top = Math.min(selection.value.y, e.offsetY)
  const width = Math.abs(selection.value.x - e.offsetX)
  const height = Math.abs(selection.value.y - e.offsetY)

  if (width <= 0 || height <= 0) return

  setTimeout(() => {
    const dpr = window.devicePixelRatio || 1
    const previewCanvas = previewRef.value
    const ctx = previewCanvas.getContext('2d', { willReadFrequently: true })

    previewCanvas.width = width * dpr
    previewCanvas.height = height * dpr

    const imageData = sourceContext.value.getImageData(
      left * dpr,
      top * dpr,
      width * dpr,
      height * dpr
    )
    ctx.putImageData(imageData, 0, 0)
  }, 0)

  previewRect.value = { left, top, width, height }
}

const handleMouseUp = () => {
  selection.value.flag = false
  toolsDisplay.value = 'block'
}

const handleEnter = (e) => {
  if (e.key === 'Enter') {
    handleSave()
  }
}

document.addEventListener('mouseup', handleMouseUp)
document.addEventListener('keydown', handleEnter)

onUnmounted(() => {
  document.removeEventListener('mouseup', handleMouseUp)
  document.removeEventListener('keydown', handleEnter)
})

window.api.on('capture-on', (e, base64) => {
  source.value = `url(${base64})`
  const dpr = window.devicePixelRatio || 1

  let image = new Image()
  image.src = base64

  image.onload = () => {
    const canvas = document.createElement('canvas')
    canvas.width = image.width
    canvas.height = image.height
    const ctx = canvas.getContext('2d', { willReadFrequently: true })
    ctx.scale(dpr, dpr)
    ctx.drawImage(image, 0, 0, image.width / dpr, image.height / dpr)

    sourceContext.value = ctx
  }
})

const handleSave = () => {
  const base64 = previewRef.value.toDataURL()
  window.api.invoke('capture-save', base64)
}
const handleCancel = () => {
  window.api.invoke('capture-off')
}
</script>

<style scoped>
.source {
  position: absolute;
  inset: 0;
  background-image: v-bind(source);
  background-size: cover;
  background-repeat: no-repeat;
}

.mask {
  position: absolute;
  inset: 0;
  background-color: rgba(0, 0, 0, 0.5);
}

.preview {
  position: absolute;
  border: 2px solid #fff;
  display: v-bind(previewRectDisplay);
}

.size {
  position: absolute;
  color: #fff;
  font-size: 14px;
  text-shadow: 0 0 10px #000;
  user-select: none;
  display: v-bind(previewRectDisplay);
}

.tool {
  position: absolute;
  display: v-bind(toolsDisplay);
}
</style>
